package com.me.study.jdk8.lambda;

import com.me.study.jdk8.methodReferences.MethodReference;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Predicate;
import org.junit.Before;
import org.junit.Test;

/**
 * 筛选出以“A”开头的人名，并打印
 *
 * 几种用法：<p>
 *     1，替代匿名内部类 <p>
 *     2，结合 FunctionalInterface <p>
 *     3，利用 Iterable.forEach() 取代 增强for循环   <p>
 *     4，利用 Method reference 代替 System.out.println(s)   <p>
 *     5，配合 Optional<T> 优雅的判断 null  <p>
 *
 * @author ME
 * @date   2019/12/24
 */
public class TestLambda2 {
    private List<String> list;

    @Test
    public void jdk7() {
        System.out.println("JDK7 写法：");
        for (String s : list) {
            if (s.startsWith("A")) {
                if (null != s) {
                    System.out.println(s);
                }
            }
        }
    }

    /** 1，替代匿名内部类 */
    @Test
    public void anonymousInnerClass() {
        System.out.println("匿名内部类遍历");
        list.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });

        System.out.println("\nlambda 遍历");
        // list.forEach(s -> {
        //     System.out.println(s);
        // });
        list.forEach(s -> System.out.println(s));

        System.out.println("\n方法引用遍历：");
        list.forEach(System.out::println);
    }

    /** 2，结合 FunctionalInterface */
    @Test
    public void with$FunctionalInterface2() {
        System.out.println("Lambda 结合 FunctionalInterface：");
        DoSomething doSomething = (list, predicate, consumer) -> {
            for (String s : list) {
                if (predicate.test(s)) {
                    consumer.accept(s);
                }
            }
        };

        doSomething.checkAndExecute(list, s -> s.startsWith("A"), s -> System.out.println(s));
        /**
         * 更简便的写法：方法引用中（引用 第一个参数实例的实例方法），见 {@link MethodReference#test4()}
          */
        // doSomething.checkAndExecute(list, s -> s.startsWith("A"), System.out::println);
    }

    /** 3，利用 Iterable.forEach() 取代 增强for循环 */
    @Test
    public void with$forEach() {
        System.out.println("利用 Iterable.forEach() 取代 增强for循环");
        for (String s : list) {
            System.out.println(s);
        }

        System.out.println();
        list.forEach(System.out::println);
    }

    /** 4，利用 Method reference 代替 System.out.println(s) */
    @Test
    public void with$MethodReference() {
        System.out.println("利用 Method reference 代替 System.out.println(s)");

        /**
         * 更简便的写法：方法引用中（引用 第一个参数实例的实例方法），见 {@link MethodReference#test4()}
         */
        list.stream().forEach(System.out::println);
    }

    @Test
    public void with$Optional() {
        System.out.println("配合 Optional<T> 优雅的判断 null");

        list.stream().forEach(s -> {
            Optional<String> strOpt = Optional.ofNullable(s);
            strOpt.ifPresent(System.out::println);
        });
    }

    @Before
    public void before() {
        String[] strArr = new String[]{ "Adam", "Arthur", "Tom", "Job" };
        list = Arrays.asList(strArr);
    }

    @FunctionalInterface
    public interface DoSomething {
        void checkAndExecute(List<String> list, Predicate<String> predicate, Consumer<String> consumer);
    }

}
